/*
* lwipGvsp.h
*
*  Copyright (C) 2022-2024 BOQ Inc. All rights reserved.
*
*  Created on: 2024年4月1日
*      Author: fitch
*/

#ifndef LWIPGVSP_H_
#define LWIPGVSP_H_

#include "stdbool.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long u64;

#define GVSP_UDP_PORT   49152
#define GVSP_MAX_RATE   120000000

#define PIXEL_MAX_VAL    ((1 << 12) - 1)
#define RETX_NUMB        32
#define US_PER_SECOND    1000000
#define TICKS_PER_US     (SYSTEM_CLINT_HZ/US_PER_SECOND)

enum GVSP_FSM_STATE {
    GVSP_FSM_IDLE,
    GVSP_FSM_LEADER,
    GVSP_FSM_PAYLOAD,
    GVSP_FSM_PADDING,
    GVSP_FSM_TRAILER
};

enum GVSP_TGR_MODE {
    GVSP_TGR_NULL,
    GVSP_TGR_AUTO,
    GVSP_TGR_SOFT,
    GVSP_TGR_RISE,
    GVSP_TGR_FALL,
    GVSP_TGR_BOTH
};

enum GVSP_AWB_MODE {
    AWB_OFF,
    AWB_ONCE,
    AWB_CONTINUE
};

struct img_leader_packet{ //Uncompressed image data 
    u16          state;
    u16       block_id;//block_id / flag
    u8 EIandPackformat;
    u8     packet_id_H;//packet_id / reserved
    u16    packet_id_L;//packet_id / reserved
    u8 fieldIdAndCount;
    u8        reserved;
    u16   payload_type;//0x0001 or 0x4001
    u32    timestamp_H;
    u32    timestamp_L;
    u32   pixel_format;
    u32         size_x;
    u32         size_y;
    u32       offset_x;
    u32       offset_y;
    u16      padding_x;
    u16      padding_y;
};

struct img_payload_packet_header {
    u16          state;
    u16       block_id;//block_id / flag
    u8 EIandPackformat;
    u8     packet_id_H;//packet_id / reserved
    u16    packet_id_L;//packet_id / reserved
    u8          data[];
};

struct img_trailer_packet{
    u16          state;
    u16       block_id;//block_id / flag
    u8 EIandPackformat;
    u8     packet_id_H;//packet_id / reserved
    u16    packet_id_L;//packet_id / reserved
    u16       reserved;
    u16   payload_type;//0x0001 or 0x4001
    u32         size_y;
};

struct img_chunk_trailer{
    struct img_trailer_packet trailer;
    u32 chunk_data_payload_length;
    u32 chunk_layout_id;
};

struct img_chunk_info {
    u32 imageId;
    u32 imageLen;
    u32 ChunkStride;
    u16 ChunkOffsetY;
    u16 ChunkOffsetX;
    u16 ChunkHeight;
    u16 ChunkWidth;
    u16 ChunkDynamicRangeMin;
    u16 ChunkDynamicRangeMax;
    u32 ChunkPixelFormat;
    u32 infoId;
    u32 infoLen;
};

struct img_chunk_timestamp {
    u64 timestamp;
    u32 timestampId;
    u32 timestampLen;
};

struct img_chunk_frame_count {
    u32 frameCount;
    u32 frameCountId;
    u32 frameCountLen;
};

struct img_chunk_trigr_count {
    u32 trigrCount;
    u32 trigrCountId;
    u32 trigrCountLen;
};

struct gvsp_camera {
u32    size;
u32   width;
u32  height;
u32  format;
u16 sof_pos;
u16 sol_pos;
u16 xOffset;
u16 yOffset;
};

typedef struct {
    u32  gvsp_reset:1;
    u32  lvds_reset:1;
    u32       CBSEL:2;
    u32         ENA:1;
    u32      CONFIG:1;
    u32         EN4:1;
    u32    cam_ctrl:1;
    u32     byr_fmt:1;
    u32     iso_out:1;
    u32  shut_start:1;
    u32     mch_sel:1;
    u32     cfg_syn:1;
    u32     led_red:1;
    u32   led_green:1;
    u32   xtrig_pol:1;
    u32    ctl_soft:1;
    u32       VMODE:1;
    u32       HMODE:1;
    u32       shift:2;
    u32 frame_reset:1;
    u32 trigr_reset:1;
    u32         XCE:1;
    u32         SCK:1;
    u32         SDO:1;
    u32         res:6;
} GVSP_CTRL_T;

typedef union {
    GVSP_CTRL_T  op;
    u32       value;
} GVSP_CTRL_REG_T;

typedef struct {
    u32 mac_sw_rst:1;
    u32 phy_sw_rst:1;
    u32    isp_sel:2;
    u32       chan:4;
    u32       mono:1;
    u32     awb_en:1;
    u32   tgr_mode:3;
    u32     pol_ok:1;
    u32     pol_ng:1;
    u32   chunk_en:1;
    u32       VBIN:3;
    u32       HBIN:3;
    u32        res:10;
} GVSP_CTRL2_T;

typedef union {
    GVSP_CTRL2_T  op;
    u32       value;
} GVSP_CTRL2_REG_T;

typedef struct {
    u32     image:1;
    u32 timestamp:1;
    u32 frame_cnt:1;
    u32 trigr_cnt:1;
    u32       res:28;
} GVSP_CHUNK_MAP_T;

typedef union {
    GVSP_CHUNK_MAP_T  map;
    u32       value;
} GVSP_CHUNK_MAP_REG_T;

typedef struct {
    u32  kB:10;
    u32  kR:10;
    u32 res:12;
} GVSP_AWB_T;

typedef union {
    GVSP_AWB_T coe;
    u32        val;
} GVSP_AWB_REG_T;

// u16 gvsp_start(const ip_addr_t *desAddr, u16 desPort);

void gvsp_loop();
void gvsp_resend(u32 blockId, u32 firstId, u32 lastId, u32 size_pkt);

u16 gvsp_stop(void);

void gvsp_led_red(bool on);

void gvsp_led_green(bool on);

u32 gvsp_cam_size(void);

void gvsp_cam_size_set(u32 size);

u32 gvsp_payload_size(void);

u32 gvsp_cam_width(void);

void gvsp_cam_width_set(u32 width);

u32 gvsp_cam_height(void);

void gvsp_cam_height_set(u32 height);

u32 gvsp_cam_format(void);

void gvsp_cam_format_set(u32 format);

u16 gvsp_cam_sof_pos(void);

u16 gvsp_cam_eof_pos(void);

u16 gvsp_cam_sol_pos(void);

u16 gvsp_cam_eol_pos(void);

void gvsp_chunk_timestamp_config(u32 val);

void gvsp_chunk_frame_counter_config(u32 val);

void gvsp_chunk_trigr_counter_config(u32 val);

void gvsp_cam_xoffset_update(u16 x);

void gvsp_cam_yoffset_update(u16 y);

void gvsp_exposure_time(u32 time);

void gvsp_trigger_on(void);

void gvsp_trigger_off(void);

void gvsp_trigger_mode(u32 mode);

void gvsp_trigger_source(u32 src);

void gvsp_trigger_software(void);

void gvsp_frame_count_reset(void);

void gvsp_trigr_count_reset(void);

void gvsp_gamma_setup(double coef);

void gvsp_blc_config(u32 val);

void gvsp_awb_en(bool en);

void gvsp_awb_red(u32 val);

void gvsp_awb_green(u32 val);

void gvsp_awb_blue(u32 val);

void gvsp_ccm_config(bool on);

void gvsp_loop(void);

void gvsp_frame_finish(void);

void gvsp_packet_resend(u16 blockId, u32 firstPktId, u32 lastPktId);

void lwipGvsp_init(void);

#ifdef __cplusplus
}
#endif

#endif /* LWIPGVSP_H_ */
